import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:xws/helpers/clip_decoration.dart';
import 'package:xws/helpers/my_selector.dart';
import 'package:xws/helpers/safe_state.dart';
import 'package:xws/helpers/safe_value_notifier.dart';
import 'package:xws/models/goods/pub_obj.dart';
import 'package:xws/res/icons.dart';
import 'package:xws/state/app_state.dart';
import 'package:xws/state/user_state.dart';
import 'package:xws/utils/app_util.dart';
import 'package:xws/utils/theme_util.dart';
import 'package:xws/widgets/ex_value_builder.dart';

import 'pub_page.dart';

/// 底部导航栏
class NavBar extends StatefulWidget {
  const NavBar({Key? key, this.onTap}) : super(key: key);

  @override
  _NavBarState createState() => _NavBarState();

  final Future<bool>? Function(int index)? onTap;
}

class _NavBarState extends State<NavBar> with SafeState<NavBar> {
  late SafeValueNotifier<int> _currentIndex;
  late SafeValueNotifier<bool> _openAdd;

  @override
  void initState() {
    super.initState();
    _currentIndex = SafeValueNotifier<int>(0);
    _openAdd = SafeValueNotifier<bool>(false);
  }

  @override
  void dispose() {
    _currentIndex.dispose();
    _openAdd.dispose();
    super.dispose();
  }

  /// 点击切换item
  Future<void> _tap(int index) async {
    if (_currentIndex.value != index) {
      if (checkUserLogin) {
        final bool check = await widget.onTap?.call(index) ?? true;
        if (check) {
          _currentIndex.value = index;
        }
      }
    }
  }

  /// 点击发布按钮
  Future<void> _tapAdd() async {
    if (!checkUserLogin) return;

    _openAdd.value = true;

    final PubObj pubObj = PubObj(k: 'pub_draft');
    pubObj.init();

    final bool? r = await push<bool>(context, PubPage(pubObj: pubObj), routeType: RouteType.slideUp);

    if (r == null || !r) {
      /// 未发布
      pubObj.save();
    } else if (r) {
      /// 已发布
      pubObj.clear();
      apps.refreshNearGoods();
      us.addApub();
    }

    _openAdd.value = false;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: sw,
      height: kBottomNavigationBarHeight + 20,
      decoration: _decoration,
      child: ExValueBuilder<int>(
        valueListenable: _currentIndex,
        child: _buildAddBtn,
        builder: (_, int index, Widget? child) {
          return Row(
            children: <Widget>[
              _navItem(0, '物品', IR.box),
              child!,
              _navItem(1, '我的', IR.me),
            ],
          );
        },
      ),
    );
  }

  /// 中心添加按钮
  Widget get _buildAddBtn {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: SizedBox(
        width: 56,
        height: 56,
        child: TextButton(
          onPressed: _tapAdd,
          style: TextButton.styleFrom(
            backgroundColor: theme(context),
            shape: const CircleBorder(),
            elevation: 10,
            shadowColor: theme(context).lighten(0.2),
          ),
          child: ExValueBuilder<bool>(
            valueListenable: _openAdd,
            child: Icon(
              Icons.add_rounded,
              size: 30,
              color: white(context),
            ),
            builder: (_, bool open, Widget? child) {
              return AnimatedRotation(
                turns: open ? 1 : 0,
                curve: Curves.ease,
                duration: open ? Duration.zero : const Duration(milliseconds: 800),
                child: child,
              );
            },
          ),
        ),
      ),
    );
  }

  /// 点击项
  Widget _navItem(int index, String tag, IconData icon) {
    Widget iconBox = Icon(
      icon,
      size: 22,
      color: _currentIndex.value == index ? theme(context) : disable(context),
    );

    if (index == 1)
      iconBox = Ms<AppState, int>.child(
        selector: (AppState a) => a.unRead,
        child: iconBox,
        builder: (int c, Widget child) {
          return Badge(
            elevation: 0,
            child: child,
            showBadge: c > 0,
            badgeContent: Container(
              width: 8,
              height: 8,
              decoration: BoxDecoration(
                color: red(context),
                shape: BoxShape.circle,
              ),
            ),
            padding: const EdgeInsets.all(1),
            position: const BadgePosition(top: -2, end: 0),
            animationType: BadgeAnimationType.scale,
            animationDuration: const Duration(milliseconds: 300),
            badgeColor: white(context),
          );
        },
      );

    return Expanded(
      child: GestureDetector(
        onTap: () => _tap(index),
        child: Container(
          color: Colors.transparent,
          padding: const EdgeInsets.only(top: 24),
          child: Center(
            child: Column(
              children: <Widget>[
                iconBox,
                Text(
                  tag,
                  style: TextStyle(
                    fontSize: 10,
                    color: _currentIndex.value == index ? theme(context) : disable(context),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  /// 样式
  Decoration get _decoration => ClipDecoration(
        clipper: const _NavClipper(),
        color: white(context),
        boxShadow: <BoxShadow>[
          BoxShadow(
            blurRadius: 16,
            color: Colors.black.withOpacity(0.03),
          ),
        ],
      );
}

class _NavClipper extends CustomClipper<Path> {
  const _NavClipper();

  @override
  Path getClip(Size size) {
    final Path path = Path();
    final double w = size.width;
    final double h = size.height;

    path.moveTo(0, 16);
    path.lineTo(w * 0.35, 16);

    path.quadraticBezierTo(w * 0.4, 16, w * 0.42, 10);

    path.quadraticBezierTo(w * 0.5, -18, w * 0.58, 10);

    path.quadraticBezierTo(w * 0.6, 16, w * 0.65, 16);

    path.lineTo(w, 16);
    path.lineTo(w, h);
    path.lineTo(0, h);
    path.close();

    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
